refactor(tui): extract attachments from document parts in session#3484
refactor(tui): extract attachments from document parts in session#3484Piyush0049 wants to merge 3 commits into
Conversation
This commit updates extractAttachmentsFromSession to properly read modern MessagePartTypeDocument attachments instead of relying solely on the legacy 'Contents of' string matching fallback, addressing the TODO in chat.go.
1104c82 to
85616ba
Compare
|
I just force-pushed to fix a trailing whitespace error that was failing the linter. The CI should pass now. |
|
Blocking issue: binary attachments round-trip as raw base64 text in the prompt. On the resend path, the extracted attachment has Suggested fixes:
|
|
Thanks for the review. I am working on the suggested fixes. |
This fixes a context overflow issue where binary attachments (like images) were being serialized as massive base64 text strings when a message was edited and resent. We now extend messages.Attachment to properly hold MimeType and Data, and rebuild the Document part natively in App.Run.
|
@dgageot I've implemented the primary suggestion to address the context overflow on the resend path. Specifically, I:
Please let me know if this looks good to you. |
Sayt-0
left a comment
There was a problem hiding this comment.
Review summary
Corrects a real data loss: editing a past message dropped modern MessagePartTypeDocument attachments because extractAttachmentsFromSession only understood the legacy Contents of <file>: <dataURL> text format. The context-overflow issue from the earlier revision is resolved by extending messages.Attachment and rebuilding a Document part through chat.ProcessAttachmentWithMetadata.
Verified on the PR branch: go build ./pkg/..., go test ./pkg/tui/... ./pkg/app/... ./pkg/chat/..., and golangci-lint all pass.
| Area | Status |
|---|---|
| Correctness (round-trip: text, binary, legacy, multi-attachment) | ok |
Image resend idempotence (Resized:false, no duplicate note) |
ok |
| Security (size and decompression-bomb guards retained) | ok |
| Tests | none added |
Doc comment on Attachment |
stale |
Unrelated cosmetic edit in processFileAttachment |
present |
Recommendation: request changes (light). The substance is approvable. Before merge: add a regression test for extractAttachmentsFromSession, refresh the stale Attachment doc comment, and drop the unrelated WriteString split. Filed as a comment rather than a blocking status since a changes-requested review is already open.
| // MimeType is the MIME type of the binary data, if Data is present. | ||
| MimeType string | ||
| // Data holds raw binary content for non-text inline attachments. | ||
| Data []byte |
There was a problem hiding this comment.
The struct's doc comment at the top of this file is now stale. It still states that the value is either FilePath or Content, and that binary support is a future extension via a MimeType hint. With Data/MimeType added here, it should document the third case (inline binary) and drop the future-tense wording.
| for i := 1; i < len(msg.MultiContent); i++ { | ||
| part := msg.MultiContent[i] | ||
|
|
||
| if part.Type == chat.MessagePartTypeDocument && part.Document != nil { |
There was a problem hiding this comment.
No regression test accompanies this change, and this is the exact path that previously shipped the context-overflow bug. A unit test on extractAttachmentsFromSession covering the four cases (Document with InlineText, Document with InlineData, legacy Contents of text, and an empty Document) would lock the behavior. The existing newTestChatPage harness plus an app.New(...) session can drive it.
| case att.Content != "": | ||
| // Inline content attachment (e.g. pasted text). | ||
| a.processInlineAttachment(att, &textBuilder) | ||
| case len(att.Data) > 0: |
There was a problem hiding this comment.
Routing binary payloads back through ProcessAttachmentWithMetadata is the right call and keeps the size and decompression-bomb guards. Worth a test for the resend path: an already-processed image re-enters ResizeImage, which returns Resized:false when it already fits within limits, so FormatDimensionNote yields no duplicate dimension note. A test would document that idempotence.
| if note := chat.FormatDimensionNote(resizeMeta); note != "" { | ||
| textBuilder.WriteString("\n" + note) | ||
| textBuilder.WriteString("\n") | ||
| textBuilder.WriteString(note) |
There was a problem hiding this comment.
Splitting WriteString("\n" + note) into two calls is behavior-preserving but unrelated to attachment extraction. Reverting it keeps the diff scoped to the feature.
|
I read the review and have worked on it. I have addressed all the requested changes. Specifically:
All tests are passing on my end. |
Description
This PR resolves a technical debt
TODOinpkg/tui/page/chat/chat.goregarding how attachments are retrieved from session history when editing a past message in the TUI.Previously,
extractAttachmentsFromSessionrelied exclusively on a text-matching fallback ("Contents of <filename>: <dataURL>"). As the codebase has evolved to useMessagePartTypeDocumentfor structured file attachments, this old extraction logic would fail to properly restore modern attachments to the message editor.Changes:
chat.MessagePartTypeDocumentto safely extractInlineTextandInlineData.InlineDatapayloads into standarddata:URIs (base64) so that image attachments render properly in the UI."Contents of "string matching strictly as a fallback (legacyPrefix) to ensure backward compatibility with older saved sessions.TODOcomment.Testing
go build ./pkg/tui/...succeeds.go test ./pkg/tui/page/chat/...passes.